package com.service;

import static com.def.GenericDef.E_BIS_PATH;
import static com.def.GenericDef.E_READ_NOT_FOUND;
import static com.def.GenericDef.E_RET_PRD_INFO;
import static com.def.GenericDef.E_XPSWITCH_INVALID_INPUT;
import static com.def.GenericDef.RETURN_CODE_OK;
import static com.def.GenericDef.RETURN_CODE_SET_ERROR;
import static com.def.GenericDef.RETURN_CODE_UNKNOWN;
import static com.def.GenericDef.RETURN_MESG_OK;
import static com.def.GenericDef.SWH_TYP_REWORK;
import static com.def.GenericDef.TRX_OUT;
import static com.def.GenericDef.T_XPSWITCH;
import static com.def.GenericDef._NORMAL;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import com.dao.IBisOpeDao;
import com.dao.IBisPathDao;
import com.dao.IBisPathSwhDao;
import com.dao.IBisPathiDao;
import com.dao.IRetPrdInfoDao;
import com.dao.IRetPrdOutDao;
import com.icim.service.ICIMBaseService;
import com.model.Bis_path;
import com.model.Bis_pathId;
import com.model.Bis_path_swh;
import com.model.Ret_prd_info;
import com.rtnBean.NotFoundRtnBeen;
import com.tx.Xpswitch.XpswitchI;
import com.tx.Xpswitch.XpswitchO;
import com.tx.Xpswitch.XpswitchOA;
import com.util.GUIDGenerator;
import com.util.MqOpe;
import com.util.Util;

@Scope("prototype")
@Service("XpswitchkService")
public class XpswitchkService extends ICIMBaseService{
	private static Logger logger = Logger.getLogger(XpswitchkService.class);
	private static String TX_NAME = T_XPSWITCH;

	private XpswitchI inTrx;
	private XpswitchO outTrx;
	private MqOpe mqOpe;

	private String gszMsgBuf = "";
	private Timestamp gEvtTimestamp;
	private String gEvtSeqID;

	@Autowired
	private IBisOpeDao bisOpeDao;
	@Autowired
	private IBisPathDao bisPathDao;
	@Autowired
	private IBisPathiDao bisPathiDao;
	@Autowired
	private IRetPrdOutDao retPrdOut;
	@Autowired
	private IBisPathSwhDao bisPathSwhDao;
	@Autowired
	private IRetPrdInfoDao retPrdInfoDao;

	public String subMainProc(String strInMsg) {
		long rtnCode = _NORMAL;

		String outMsg = null;
		gszMsgBuf = "";
		gEvtTimestamp = Util.getCurrentTimestamp();
		gEvtSeqID = GUIDGenerator.javaGUID();
		inTrx = new XpswitchI();
		outTrx = new XpswitchO();
		outTrx.setTrx_id(TX_NAME);
		outTrx.setType_id(TRX_OUT);
		outTrx.setRtn_code(String.valueOf(RETURN_CODE_SET_ERROR));
		mqOpe = new MqOpe();

		try {
			inTrx = (XpswitchI) mqOpe.inStr2Obj(strInMsg, inTrx);
			logger.info("InTrx is " + strInMsg);

			rtnCode = subMainProc2(inTrx.getAction_flg().toCharArray()[0]);
			if (rtnCode != _NORMAL) {
				TransactionAspectSupport.currentTransactionStatus()
						.setRollbackOnly();
				outTrx.setRtn_code(String.valueOf(rtnCode));
				outTrx.setRtn_mesg(gszMsgBuf);
			} else {
				outTrx.setRtn_code(String.valueOf(RETURN_CODE_OK));
				outTrx.setRtn_mesg(RETURN_MESG_OK);
				bisPathSwhDao.flushCurSession();
			}
		} catch (Exception ex) {
			TransactionAspectSupport.currentTransactionStatus()
					.setRollbackOnly();
			outTrx.setRtn_mesg(ex.toString());
			outTrx.setRtn_code(RETURN_CODE_UNKNOWN);
			logger.error(Util.stackTraceToString(ex));
		} finally {
			outMsg = mqOpe.obj2Str(outTrx);
			return outMsg;
		}
	}

	/**
	 * All move in logic
	 * 
	 * @return
	 */
	private long subMainProc2(char actionType) {
		long lRc = _NORMAL;

		switch (actionType) {
		case 'G': {
			lRc = getPathSwh(inTrx.getPath_id(), inTrx.getPath_ver(),
					inTrx.getOpe_no(), inTrx.getSwh_type());
			if (lRc != _NORMAL) {
				return lRc;
			}
			break;
		}
		case 'B': {
			lRc = getReworkSwhByPrd();
			if (lRc != _NORMAL) {
				return lRc;
			}
			break;
		}
		default: {
			gszMsgBuf = "Invalide type input: [" + actionType + "]";
			return E_XPSWITCH_INVALID_INPUT;
		}
		}

		return _NORMAL;
	}

	/**
	 * 根据箱号信息查询当前箱子可以转入的switch列表（有产品的入账箱子）
	 * 
	 * @return
	 */
	private long getReworkSwhByPrd() {
		long lRc = _NORMAL;
		String boxID = inTrx.getBox_id();
		List<Ret_prd_info> ret_prd_infoList = new ArrayList<Ret_prd_info>();
		ret_prd_infoList = retPrdInfoDao.getShtListInfo(boxID);
		if (null == ret_prd_infoList) {
			gszMsgBuf = "No prd in box [" + boxID + "] !";
			return E_RET_PRD_INFO + E_READ_NOT_FOUND;
		}

		lRc = getPathSwh(ret_prd_infoList.get(0).getNx_path_id_fk(),
				ret_prd_infoList.get(0).getNx_path_ver_fk(), ret_prd_infoList
						.get(0).getNx_ope_no_fk(), SWH_TYP_REWORK);
		if (_NORMAL != lRc) {
			return lRc;
		}

		return _NORMAL;
	}

	/**
	 * 查询switch信息
	 * 
	 * @return
	 */
	private long getPathSwh(String path_id, String path_ver, String ope_no,
			String swh_typ) {
		long lRc = _NORMAL;
		Bis_path bis_path = new Bis_path();
		Bis_pathId bis_pathId = new Bis_pathId();

		bis_pathId.setPath_id_fk(path_id);
		bis_pathId.setPath_ver_fk(path_ver);
		bis_pathId.setCr_ope_no(ope_no);
		bis_path = bisPathDao.get(bis_pathId);
		if (null == bis_path) {
			gszMsgBuf = new NotFoundRtnBeen(bis_pathId.toString(),
					Bis_path.class).toString();
			return E_BIS_PATH + E_READ_NOT_FOUND;
		}

		List<Bis_path_swh> bis_path_swhList = new ArrayList<Bis_path_swh>();
		bis_path_swhList = bisPathSwhDao.getPathSwh(bis_path, swh_typ);
		setOutTrx(bis_path_swhList);

		return _NORMAL;
	}

	/**
	 * 根据Bis_path_swh List为outTrx赋值
	 * 
	 * @param bis_path_swhList
	 * @return
	 */
	private long setOutTrx(List<Bis_path_swh> bis_path_swhList) {
		outTrx.setSwh_cnt(0);
		if (null != bis_path_swhList && !bis_path_swhList.isEmpty()) {
			List<XpswitchOA> oary = new ArrayList<XpswitchOA>();
			for (int i = 0, size = bis_path_swhList.size(); i < size; i++) {
				XpswitchOA xpswitchOA = new XpswitchOA();
				xpswitchOA.setFr_path_id_fk(bis_path_swhList.get(i).getId()
						.getFr_path_id_fk());
				xpswitchOA.setFr_path_ver_fk(bis_path_swhList.get(i).getId()
						.getFr_path_ver_fk());
				xpswitchOA.setFr_ope_no_fk(bis_path_swhList.get(i).getId()
						.getFr_ope_no_fk());
				xpswitchOA.setSwh_id(bis_path_swhList.get(i).getId()
						.getSwh_id());
				xpswitchOA.setSwh_typ(bis_path_swhList.get(i).getId()
						.getSwh_typ());

				xpswitchOA.setSwh_dsc(bis_path_swhList.get(i).getSwh_dsc());
				xpswitchOA.setSwh_path_id_fk(bis_path_swhList.get(i)
						.getSwh_path_id_fk());
				xpswitchOA.setSwh_path_ver_fk(bis_path_swhList.get(i)
						.getSwh_path_ver_fk());
				xpswitchOA.setOut_path_id_fk(bis_path_swhList.get(i)
						.getOut_path_id_fk());
				xpswitchOA.setOut_path_ver_fk(bis_path_swhList.get(i)
						.getOut_path_ver_fk());
				xpswitchOA.setOut_ope_no_fk(bis_path_swhList.get(i)
						.getOut_ope_no_fk());
				oary.add(xpswitchOA);
			}
			outTrx.setOary(oary);
			outTrx.setSwh_cnt(bis_path_swhList.size());
		}
		return _NORMAL;
	}

}
